

import * as fs from "fs"
import { DictUnit } from "./trie"

export function readFile(path: string) {

    const buffer = fs.readFileSync(path)
    let len = buffer.length

    if (len >= 2 && buffer[0] === 0xFE && buffer[1] === 0xFF) {

        len &= ~1

        for (let i = 0; i < len; i += 2) {

            const temp = buffer[i]
            buffer[i] = buffer[i + 1]
            buffer[i + 1] = temp

        }

        return buffer.toString("utf16le", 2)

    }

    if (len >= 2 && buffer[0] === 0xFF && buffer[1] === 0xFE) {

        return buffer.toString("utf16le", 2)

    }

    if (len >= 3 && buffer[0] === 0xEF && buffer[1] === 0xBB && buffer[2] === 0xBF) {

        return buffer.toString("utf8", 3)

    }

    return buffer.toString("utf8")

}

export function createObj<T>(): T {
    let v = Object.create(null)
    v.__ = null
    delete v.__
    return v
}

export interface PTMap<T> {
    k: string
    v: T
}

export interface PMap<T> {
    k: number
    v: T
}

export function createPTMap<T>(): PTMap<T> {
    return createObj<PTMap<T>>()
}

export interface Weight{    
    weight: number

}

export interface Word extends Weight{
    word: string
    offsets: number[]
}

export function createPMap<T>(): PMap<T> {
    return createObj<PMap<T>>()
}

export const enum Comparison {
    LessThan = -1,
    EqualTo = 0,
    GreaterThan = 1
}

export function weightCompare_V<T extends Weight>(a: T, b: T): Comparison {
    if (a === b) return Comparison.EqualTo
    if (a === undefined || a.weight === undefined) return Comparison.GreaterThan
    if (b === undefined || b.weight === undefined) return Comparison.LessThan
    if (a.weight === b.weight) return Comparison.EqualTo
    return a.weight > b.weight ? Comparison.LessThan : Comparison.GreaterThan
}

export function weightCompare_A<T extends Weight>(a: T, b: T): Comparison {
    if (a === b) return Comparison.EqualTo
    if (a === undefined || a.weight === undefined) return Comparison.LessThan
    if (b === undefined || b.weight === undefined) return Comparison.GreaterThan
    if (a.weight === b.weight) return Comparison.EqualTo
    return a.weight > b.weight ? Comparison.GreaterThan : Comparison.LessThan
}
